home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_number / small_integer.e < prev   
Text File  |  2000-03-25  |  9KB  |  364 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class SMALL_INTEGER
  13. --
  14. -- To implement NUMBER (do not use this class, see NUMBER).
  15. --
  16. inherit ABSTRACT_INTEGER;
  17.    
  18. creation make
  19.    
  20. feature
  21.  
  22.    is_zero: BOOLEAN is
  23.       do
  24.      Result := value = 0;
  25.       end;
  26.    
  27.    is_one: BOOLEAN is
  28.       do
  29.      Result := value = 1;
  30.       end;
  31.    
  32.    is_positive: BOOLEAN is
  33.       do
  34.      Result := value >= 0;
  35.       end;
  36.  
  37.    is_negative: BOOLEAN is
  38.       do
  39.      Result := value < 0;
  40.       end;
  41.  
  42.    to_integer: INTEGER is
  43.       do
  44.      Result := value;
  45.       end;
  46.    
  47.    to_double: DOUBLE is
  48.       do
  49.      Result := value;
  50.       end;   
  51.    
  52.    prefix "-" : NUMBER is
  53.       do
  54.      !SMALL_INTEGER!Result.make(- value);
  55.       end;
  56.  
  57.    infix "+" (other: NUMBER): NUMBER is
  58.       do
  59.      Result := other @+ value;
  60.       end;
  61.    
  62.    infix "@+" (other: INTEGER): NUMBER is
  63.       local
  64.      sum : INTEGER
  65.       do
  66.      sum := value + other;
  67.      if is_positive and (other >= 0) and (sum < 0) then
  68.         !LARGE_POSITIVE_INTEGER!Result.make_smaller(sum - Base)
  69.      elseif is_negative and (other < 0) and (sum > 0) then
  70.         !LARGE_NEGATIVE_INTEGER!Result.make_smaller(-sum - Base)
  71.      elseif (sum = -Base) then
  72.         Result := greater_large_negative_integer;
  73.      else
  74.         !SMALL_INTEGER!Result.make(sum);
  75.      end;
  76.       end;
  77.    
  78.    infix "*" (other: NUMBER): NUMBER is
  79.       do
  80.      if is_zero then
  81.         Result := zero;
  82.      else
  83.         Result := other @* value;
  84.      end;
  85.       end;
  86.    
  87.    infix "@*" (other : INTEGER): NUMBER is
  88.       local
  89.      results_sign, is_mini, other_is_mini: BOOLEAN; 
  90.      int : INTEGER;
  91.       do
  92.      if (other = 1) then
  93.         Result := Current;
  94.      else        
  95.         results_sign := (is_positive = (other >= 0));
  96.         is_mini := value = Minimum_integer;
  97.         other_is_mini := other = Minimum_integer;
  98.         if is_mini or other_is_mini then
  99.            if is_mini and other_is_mini then
  100.           !LARGE_POSITIVE_INTEGER!Result.make_big;
  101.            else
  102.           if other_is_mini then
  103.              int := value.abs;
  104.           else
  105.              int := other.abs;
  106.           end;     
  107.           if results_sign then
  108.              !LARGE_POSITIVE_INTEGER!Result.make_from_product(int);
  109.           else
  110.              !LARGE_NEGATIVE_INTEGER!Result.make_from_product(int);
  111.           end;
  112.            end;
  113.         else
  114.            mult_2_integer(value.abs, other.abs);
  115.            if results_sign then
  116.           if (temp_2_digints @ 1) /= 0 then 
  117.              !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(
  118.                                                          clone(temp_2_digints));
  119.           else
  120.              !SMALL_INTEGER!Result.make(temp_2_digints @ 0);
  121.           end;
  122.            else 
  123.           if ((temp_2_digints @ 1) = 0) then 
  124.              !SMALL_INTEGER!Result.make(-(temp_2_digints @ 0));
  125.           else
  126.              if ((temp_2_digints @ 1)= 1) 
  127.             and ((temp_2_digints @ 0)=0) then 
  128.             Result := greater_large_negative_integer;
  129.              else
  130.             !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(
  131.                                                           clone(temp_2_digints));
  132.              end;
  133.           end;
  134.            end;
  135.         end;
  136.      end;     
  137.       end; 
  138.    
  139.    infix "@/" (other: INTEGER): NUMBER is
  140.       local
  141.      tmp: SMALL_FRACTION;
  142.      n, d: ABSTRACT_INTEGER;
  143.       do
  144.      if (other = 1) then
  145.         Result := Current;
  146.      else        
  147.         if (value \\ other) = 0  then
  148.            !SMALL_INTEGER!Result.make(value // other);
  149.         elseif (other = Minimum_integer) then
  150.            n ?= abs;
  151.            d ?= greater_large_negative_integer.abs;
  152.            !LARGE_FRACTION!Result.make( n, d, is_positive);           
  153.         else           
  154.            Result := tmp.from_two_integer(value,other);
  155.         end;
  156.      end;
  157.       end; 
  158.    
  159.    infix "//" (other: NUMBER): NUMBER is
  160.       local
  161.      oth: ABSTRACT_INTEGER;
  162.       do
  163.      oth ?= other;
  164.      Result := oth.integer_divide_small_integer(Current);
  165.       end;
  166.    
  167.    infix "@//" (other: INTEGER): NUMBER is
  168.       do
  169.      !SMALL_INTEGER!Result.make(value // other);
  170.       end;
  171.    
  172.    infix "\\" (other: NUMBER): NUMBER is
  173.       local
  174.      oth: ABSTRACT_INTEGER;
  175.       do
  176.      oth ?= other;
  177.      Result := oth.remainder_of_divide_small_integer(Current);
  178.       end;
  179.    
  180.    infix "@\\" (other : INTEGER): NUMBER is
  181.       do
  182.      !SMALL_INTEGER!Result.make(value \\ other);
  183.       end;
  184.    
  185.    
  186.    infix "@=" (other: INTEGER): BOOLEAN is
  187.       do
  188.      Result := value = other;
  189.       end;
  190.    
  191.    infix "@<" (other: INTEGER): BOOLEAN is
  192.       do
  193.      Result := value < other;
  194.       end;
  195.    
  196.    infix "@<=" (other: INTEGER): BOOLEAN is
  197.       do
  198.      Result := value <= other;
  199.       end;   
  200.    
  201.    infix "@>" (other: INTEGER): BOOLEAN is
  202.       do
  203.      Result := value > other;
  204.       end;
  205.    
  206.    infix "@>=" (other: INTEGER): BOOLEAN is
  207.       do
  208.      Result := value >= other;
  209.       end;
  210.    
  211.    infix "#=" (other: DOUBLE): BOOLEAN is
  212.       do
  213.      Result := other = value;
  214.       end;
  215.    
  216.    infix "#<" (other: DOUBLE): BOOLEAN is
  217.       do
  218.      Result := value < other;
  219.       end;
  220.    
  221.    infix "#<=" (other: DOUBLE): BOOLEAN is
  222.       do
  223.      Result := value <= other;
  224.       end;
  225.    
  226.    infix "#>" (other: DOUBLE): BOOLEAN is
  227.       do
  228.      Result := value > other;
  229.       end;
  230.    
  231.    infix "#>=" (other: DOUBLE): BOOLEAN is
  232.       do
  233.      Result := value >= other;
  234.       end;
  235.       
  236.    infix "<" (other: NUMBER): BOOLEAN is
  237.       do
  238.      Result := other @> value;
  239.       end;
  240.    
  241.    is_equal(other: like Current): BOOLEAN is
  242.       do
  243.      Result := value = other.value;
  244.       end; 
  245.    
  246. feature {NUMBER}   
  247.    
  248.    value: INTEGER;
  249.    
  250.    add_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  251.       do
  252.      Result:= other @+ value;
  253.       end;
  254.    
  255.    add_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  256.       do 
  257.      Result:= other @+ value;
  258.       end;
  259.    
  260.    add_with_small_fraction (other: SMALL_FRACTION ): NUMBER is
  261.       do
  262.      Result:= other @+ value;
  263.       end;
  264.    
  265.    add_with_large_fraction (other: LARGE_FRACTION): NUMBER is
  266.       do
  267.      Result := other @+ value;
  268.       end;
  269.       
  270.    multiply_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  271.       do
  272.      Result:=other.multiply_with_small_integer(Current);
  273.       end;
  274.    
  275.    multiply_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  276.       do 
  277.      Result:=other.multiply_with_small_integer(Current);
  278.       end;
  279.    
  280.    multiply_with_small_fraction (other: SMALL_FRACTION): NUMBER is
  281.       do
  282.      Result:=other.multiply_with_small_integer(Current);
  283.       end;
  284.    
  285.    multiply_with_large_fraction (other: LARGE_FRACTION): NUMBER is
  286.       do
  287.      Result := other.multiply_with_small_integer(Current); 
  288.       end;
  289.    
  290.    integer_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  291.       do
  292.      Result ?= other @// value;
  293.       end;
  294.       
  295.    integer_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  296.       do
  297.      Result ?= other @// value;
  298.       end;
  299.    
  300.    integer_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  301.       do
  302.      Result ?= other @// value;      
  303.       end;
  304.    
  305.    remainder_of_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  306.       do
  307.      Result ?= other @\\ value;
  308.       end; 
  309.             
  310.    remainder_of_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  311.       do
  312.      Result ?= other @\\ value;
  313.       end;
  314.    
  315.    remainder_of_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  316.       do
  317.      Result ?= other @\\ value;
  318.       end;
  319.    
  320.    inverse: NUMBER is
  321.       do          
  322.      if (is_one) or else (Current @= -1) then
  323.         Result := Current;
  324.      else
  325.         !SMALL_FRACTION!Result.make(sign, value.abs);
  326.      end;
  327.       end;
  328.    
  329.    greater_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): BOOLEAN is 
  330.       do
  331.       end;
  332.     
  333.    greater_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): BOOLEAN is 
  334.       do
  335.      Result := true; 
  336.       end;
  337.    
  338.    greater_with_small_fraction(other: SMALL_FRACTION): BOOLEAN is  
  339.       do   
  340.      Result := (Current @* other.denominator) @> other.numerator; 
  341.       end;  
  342.    
  343.    greater_with_large_fraction(other: LARGE_FRACTION): BOOLEAN is  
  344.       do   
  345.      if other.is_negative then
  346.          Result := (other.denominator * Current) > (- other.numerator);
  347.      else
  348.         Result := (other.denominator * Current) > other.numerator;
  349.      end;
  350.       end;     
  351.    
  352. feature {NONE}
  353.    
  354.    make(val: INTEGER) is
  355.       do
  356.      value := val;
  357.       end;
  358.  
  359. invariant   
  360.    
  361.    value /= Minimum_integer;
  362.    
  363. end
  364.